Skip to content

Comments

fix: 아카이브 기능 버그 해결#378

Merged
Hyeonjun0527 merged 1 commit intodevelopfrom
fix/archive
Feb 4, 2026
Merged

fix: 아카이브 기능 버그 해결#378
Hyeonjun0527 merged 1 commit intodevelopfrom
fix/archive

Conversation

@Hyeonjun0527
Copy link
Member

@Hyeonjun0527 Hyeonjun0527 commented Feb 4, 2026

🌱 연관된 이슈

☘️ 작업 내용

아카이브 기능 버그 해결

🍀 참고사항

스크린샷 (선택)

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 아카이브 항목에 링크 필드 추가
  • 접근성 개선

    • UI 버튼에 ARIA 레이블·접근성 속성 추가
    • 모달의 닫기 버튼 레이블 추가
    • 필터·토글 버튼에 명시적 버튼 타입 지정(키보드/폼 동작 개선)
  • 개선사항

    • MVP 팀 주차 레이블을 동적으로 표시
    • 순위 배지 아이콘 렌더링 개선
    • 투표 ID 처리 로직 강화

@Hyeonjun0527 Hyeonjun0527 self-assigned this Feb 4, 2026
@vercel
Copy link

vercel bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
study-platform-client-dev Ready Ready Preview, Comment Feb 4, 2026 3:23pm

@coderabbitai
Copy link

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

문서 하나 삭제(Balance Game 태그 필터 문서), API 로거에 페이로드 로깅 제어·절단 추가, UI 접근성·버튼 타입 명시, 여러 훅/API에서 limitsize 파라미터 통일, 아카이브에 link 필드 및 편집 UI 추가, 명성의 전당 UI/아이콘 개선, 투표 ID 디코더에 bigint 처리 추가.

Changes

Cohort / File(s) Summary
문서 제거
docs/balance-game-tag-filter-request.md
Balance Game 태그 필터 관련 문서 전체 삭제.
API 로깅 개선
src/api/client/api-logger.ts
shouldLogPayloads 게이팅, MAX_LOG_LENGTH, 값 정제/잘라내기(sanitize/truncate), 안전한 stringify 및 페이로드 로깅 조건부 처리 추가.
UI 접근성 · 버튼 타입
src/components/ui/filters/sort-dropdown.tsx, src/components/ui/filters/view-mode-toggle.tsx, src/components/ui/modal-shell.tsx, src/features/study/one-to-one/history/ui/study-history-header.tsx
버튼에 type="button" 명시와 aria-label/aria-pressed 등 ARIA 속성 추가(접근성 개선).
limit → size 파라미터 통일 (API · 훅)
src/components/voting/voting-create-modal.tsx, src/features/study/one-to-one/archive/api/get-archive-search-suggestions.ts, src/features/study/one-to-one/archive/model/archive-keys.ts, src/features/study/one-to-one/archive/model/use-archive-search-suggestions-query.ts, src/features/study/one-to-one/archive/ui/archive-filters.tsx, src/features/study/one-to-one/balance-game/api/balance-game-api.ts, src/features/study/one-to-one/balance-game/model/balance-game-keys.ts, src/features/study/one-to-one/balance-game/model/use-balance-game-query.ts, src/features/study/one-to-one/balance-game/ui/community-tab-client.tsx, src/types/archive.ts
공용 API/훅에서 limit 파라미터명을 size로 변경(디폴트값 유지), 쿼리 파라미터·쿼리키 일관성 갱신.
아카이브: link 필드 추가 (API)
src/features/study/one-to-one/archive/api/update-archive.ts
UpdateArchiveRequestlink?: string 추가, 응답에 link: string 포함.
아카이브 UI: 링크 편집 기능
src/features/study/one-to-one/archive/ui/archive-grid.tsx, src/features/study/one-to-one/archive/ui/archive-list.tsx
편집 모드에 link 상태 추가 및 입력 필드 렌더링, 저장 시 변경된 링크 전송, 이펙트 의존성에 item.link 포함.
명성의 전당: 레이블·아이콘·리스트 개선
src/features/study/one-to-one/hall-of-fame/ui/mvp-team-card.tsx, src/features/study/one-to-one/hall-of-fame/ui/rank-badge.tsx, src/features/study/one-to-one/hall-of-fame/ui/ranker-list-item.tsx
MVP 팀 주차 레이블을 동적 계산으로 변경, 랭크 아이콘을 SVG 컴포넌트로 직접 교체, 리스트 항목 트리거를 divbutton으로 변경(접근성 개선).
투표 ID 디코더 개선
src/utils/voting-id.ts
decodeVotingId가 bigint 결과 처리: 안전한 정수이면 Number로 반환, 아니면 null. 유지되는 encodeVotingId.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 문서 떠나고 접근성 높여
limit는 size로, 아카이브엔 link가 와서
로깅은 조심스레 자르고, 아이콘은 반짝이며
버튼은 명확히 눌러지고, bigint도 안심하네 🌱

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive PR 제목은 '아카이브 기능 버그 해결'로, 주요 변경사항인 아카이브 관련 기능 개선을 지칭하나 구체적 내용이 불명확합니다. 제목을 '아카이브 링크 필드 추가 및 검색 파라미터 개선' 같이 구체적으로 수정하여 변경사항을 명확히 하세요.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/archive

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/api/client/api-logger.ts`:
- Around line 27-46: sanitizeValue can recurse infinitely on circular objects;
update it to accept/use a WeakSet (e.g., visited) to track visited object nodes,
check visited.has(obj) before recursing and return a safe sentinel (like
"[Circular]" or null) when detected, and add the object to visited before
descending into arrays/objects; apply this to the Array.isArray and typeof value
=== 'object' branches so truncate/sanitizeValue calls use the same visited set
to prevent stack overflow.
🧹 Nitpick comments (5)
src/features/study/one-to-one/archive/ui/archive-grid.tsx (1)

136-142: 링크 입력 필드에 유효성 검사 또는 길이 제한 추가를 고려하세요.

title과 description 입력에는 maxLength가 설정되어 있지만, 링크 입력에는 제한이 없습니다. URL 형식 검증이나 최대 길이 제한을 추가하면 사용자 경험과 데이터 무결성이 향상될 수 있습니다.

💡 maxLength 추가 예시
 <BaseInput
   id={`archive-link-${item.id}`}
   value={link}
   onChange={(e) => setLink(e.target.value)}
   placeholder="링크"
   className="w-full"
+  maxLength={2048}
 />
src/features/study/one-to-one/archive/ui/archive-list.tsx (2)

136-142: 링크 입력 필드에 유효성 검사 또는 길이 제한 추가를 고려하세요.

archive-grid.tsx와 동일하게, 이 컴포넌트의 링크 입력에도 maxLength 제한이 없습니다. 일관성을 위해 두 컴포넌트 모두 동일한 제한을 적용하는 것이 좋습니다.

💡 maxLength 추가 예시
 <BaseInput
   id={`archive-link-${item.id}`}
   value={link}
   onChange={(e) => setLink(e.target.value)}
   placeholder="링크"
   className="w-full"
+  maxLength={2048}
 />

37-87: LibraryCardLibraryRow 간의 편집 로직 중복을 추후 리팩토링 고려

archive-grid.tsxLibraryCard와 이 파일의 LibraryRow가 거의 동일한 상태 관리 및 핸들러 로직(title, description, link, nextPrivate 상태, useEffect 동기화, handleSave, handleCancel)을 공유하고 있습니다.

향후 유지보수성 향상을 위해 공통 로직을 커스텀 훅으로 추출하는 것을 고려해 보세요.

💡 커스텀 훅 추출 예시
// useArchiveEditing.ts
export function useArchiveEditing(item: ArchiveItem) {
  const [isEditing, setIsEditing] = React.useState(false);
  const [title, setTitle] = React.useState(item.title);
  const [description, setDescription] = React.useState(item.description ?? '');
  const [link, setLink] = React.useState(item.link ?? '');
  const [nextPrivate, setNextPrivate] = React.useState(!!item.isPrivate);

  React.useEffect(() => {
    if (!isEditing) {
      setTitle(item.title);
      setDescription(item.description ?? '');
      setLink(item.link ?? '');
      setNextPrivate(!!item.isPrivate);
    }
  }, [isEditing, item.title, item.description, item.link, item.isPrivate]);

  const buildUpdateRequest = (): UpdateArchiveRequest | null => {
    const request: UpdateArchiveRequest = {};
    // ... 변경 감지 로직
    return Object.keys(request).length > 0 ? request : null;
  };

  const resetFields = () => {
    setTitle(item.title);
    setDescription(item.description ?? '');
    setLink(item.link ?? '');
    setNextPrivate(!!item.isPrivate);
  };

  return {
    isEditing, setIsEditing,
    title, setTitle,
    description, setDescription,
    link, setLink,
    nextPrivate, setNextPrivate,
    buildUpdateRequest,
    resetFields,
  };
}
src/features/study/one-to-one/hall-of-fame/ui/mvp-team-card.tsx (1)

17-33: 주차 계산 로직 검토가 필요합니다.

현재 로직은 해당 월의 첫 번째 날의 요일을 기준으로 주차를 계산합니다. 이 방식이 비즈니스 요구사항(예: ISO 주차, 일요일/월요일 시작 등)과 일치하는지 확인이 필요합니다.

또한, IIFE 대신 useMemo를 사용하면 의존성이 명확해지고 불필요한 재계산을 방지할 수 있습니다.

♻️ useMemo 활용 제안
+'use client';
+
+import { Trophy, Flame } from 'lucide-react';
+import React, { useMemo } from 'react';
...

export default function MVPTeamCard({ team, className }: MVPTeamCardProps) {
-  const weekLabel = (() => {
+  const weekLabel = useMemo(() => {
    const dateSource = team.weekDate || team.weekStartDate;
    if (!dateSource) return 'MVP 팀';

    const date = new Date(dateSource);
    if (Number.isNaN(date.getTime())) return 'MVP 팀';

    const firstDayOfMonth = new Date(
      date.getFullYear(),
      date.getMonth(),
      1,
    ).getDay();
    const weekOfMonth =
      Math.floor((date.getDate() + firstDayOfMonth - 1) / 7) + 1;

    return `${date.getMonth() + 1}월 ${weekOfMonth}주차 MVP 팀`;
-  })();
+  }, [team.weekDate, team.weekStartDate]);
src/features/study/one-to-one/hall-of-fame/ui/rank-badge.tsx (1)

13-14: 중첩 삼항 연산자 가독성 개선을 고려해 주세요.

현재 로직은 동작하지만, 객체 매핑을 사용하면 확장성과 가독성이 향상됩니다.

♻️ 객체 매핑 방식 제안
+const RANK_ICONS: Record<number, React.ComponentType<React.SVGProps<SVGSVGElement>>> = {
+  1: GoldRankIcon,
+  2: SilverRankIcon,
+};

 export default function RankBadge({ rank }: RankBadgeProps) {
-  const Icon =
-    rank === 1 ? GoldRankIcon : rank === 2 ? SilverRankIcon : BronzeRankIcon;
+  const Icon = RANK_ICONS[rank] ?? BronzeRankIcon;

refactor: 코드래빗반영
@Hyeonjun0527 Hyeonjun0527 merged commit 113bb1c into develop Feb 4, 2026
8 of 9 checks passed
@Hyeonjun0527 Hyeonjun0527 deleted the fix/archive branch February 4, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant